﻿using Rabbit.Common;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rabbit.Provider.Dead
{
    /// <summary>
    /// 死信(有效期)
    /// </summary>
    internal class SendDead
    {
        /// <summary>
        /// 发送死信(有效期)
        /// </summary>
        public static void SendDeadMsg()
        {
            //创建连接
            using (var connection = RabbitMQHelper.GetConnect())
            {
                //创建信道
                using (var channel = connection.CreateModel())
                {
                    #region 生产端  消费端
                    string normalExName = "NormalExchange";//正常交换机名称
                    string normalQueName = "NormalQue";//正常队列名称
                    string normalKey = "NormalKey";//正常路由名称

                    string deadExName = "DeadExchange";//死信交换机名称
                    string deadQueName = "DeadQue";//死信队列名称
                    string deadKey = "DeadKey";//死信路由名称

                    //声明正常交换机
                    channel.ExchangeDeclare(exchange: normalExName, type: "direct", durable: false, false, null);
                    // 创建声明正常队列
                    Dictionary<string, object> para = new Dictionary<string, object>();//定义字典
                    para.Add("x-dead-letter-exchange", deadExName);//死信交换机的名称
                    para.Add("x-dead-letter-routing-key", deadKey);//死信路由名称
                    //para.Add("x-max-length",10);//(2)最多10条
                    channel.QueueDeclare(normalQueName, durable: false, false, false, para);
                    // 绑定正常队列
                    channel.QueueBind(normalQueName, normalExName, normalKey, null);


                    //声明死信交换机
                    channel.ExchangeDeclare(exchange: deadExName, type: "direct", durable: false, false, null);
                    // 创建声明死信队列
                    channel.QueueDeclare(deadQueName, durable: false, false, false, null);
                    // 绑定死信队列
                    channel.QueueBind(deadQueName, deadExName, deadKey, null);
                    #endregion


                    //发送消息(向正常队列发送)
                    //信道创建属性
                    //var prop = channel.CreateBasicProperties();
                    //(1)消息TTL(Time To Live 存活时长)过期。 死信
                    //prop.Expiration = "10000";//设置有效期 单位毫秒  10s

                //抢票秒杀业务

                //应用场景: 为了保证订单业务的消息数据不丢失，需要使用到RabbitMQ的死信队列机制，
                //当消息消费发生异常时，将消息投入死信队列中。还有比如说: 用户在商城下单成功
                //并点击去支付后在指定时间未支付时自动失效。

                    int i = 0;
                    while (i < 15)
                    {
                        string message = $"测试死信 发送的第{i}条消息";
                        var body = Encoding.UTF8.GetBytes(message);
                        channel.BasicPublish(exchange: normalExName, routingKey: normalKey, null, body);//prop
                        Console.WriteLine($"测试死信,第{i}条消息发送成功");
                        i++;
                    }

                }
            }
        }
    }

}
